package com.banggood.upms.aspect;

import com.banggood.upms.bean.po.AuditLog;
import com.banggood.upms.service.AuditLog.AuditLogService;
import com.banggood.upms.common.component.CommonComponent;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Aspect
@Order(1)
@Component
public class AuditLogAspect {

    protected final Log logger = LogFactory.getLog(this.getClass());
    @Autowired
    private AuditLogService auditLogService;
    @Autowired
    private CommonComponent component;

    /**
     * #1，不可以切入AuditLogServiceImpl审计业务层的逻辑，否则会造成无限循环切入，直到内存溢出
     * #2，查询操作不做审计
     */
    @Pointcut("execution(public * com.banggood.upms.service.impl.*.*(..)) " +
            "&& !execution(public * com.banggood.upms.service.AuditLog.AuditLogServiceImpl.*(..)) " +
            "&& !execution(public * com.banggood.upms.service.impl.*.select*(..))" +
            "&& !execution(public * com.banggood.upms.service.impl.*.if*(..))")
    public void insertAuditLog(){}

    @Before("insertAuditLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        StringBuffer operationLog = new StringBuffer();
        operationLog.append("ARGS : ")
                .append(Arrays.toString(joinPoint.getArgs()));
        StringBuffer operationType = new StringBuffer();
        operationType.append("CLASS_METHOD : ")
                .append(joinPoint.getSignature().getDeclaringTypeName())
                .append(".")
                .append(joinPoint.getSignature().getName());
        AuditLog auditLog = new AuditLog();
        auditLog.setOperationLog(operationLog.toString());
        auditLog.setId(component.generateId());
        auditLog.setOperationType(operationType.toString());
//        auditLogService.insert(auditLog);
        logger.debug("入库的审计信息：" + auditLog.toString());
    }

    @AfterReturning(returning = "resp", pointcut = "insertAuditLog()")
    public void doAfterReturning(Object resp) throws Throwable {
        logger.debug("Insert audit log successfully: " + resp);
    }
}

